package c2.cross.business.rank.h;

import c2.cross.business.rank.CrossRankDao;
import cate.game.rank.po.Rank;
import cate.game.role.RoleSnapshot;
import easy.java.dev.note.NoteField;

import java.util.Comparator;
import java.util.List;


public abstract class BaseExtraValueRankHandler extends BaseSingleValueRankHandler{
    @NoteField(value = "类型")
    private Type type;

    public BaseExtraValueRankHandler(int rankId, CrossRankDao dao) {
        this(rankId, dao, Type.VALUE_BIG_EXTRA_BIG_NIUBI);
    }

    public BaseExtraValueRankHandler(int rankId, CrossRankDao dao, Type type) {
        super(rankId, dao);
        if (type != null) {
            this.type = type;
        } else {
            this.type = Type.VALUE_BIG_EXTRA_BIG_NIUBI;
        }
    }

    /**
     * 记录数值
     *
     * @param snapshot 角色快照
     * @param newValue 新记录值
     */
    @Override
    public void record(RoleSnapshot snapshot, long newValue) {
        throw new UnsupportedOperationException("不支持的操作，请使用BaseSingleValueRankHandler");
    }

    public synchronized void record(RoleSnapshot snapshot, long value, long extraValue) {
        if (snapshot == null) {
            return;
        }
        List<Rank> list = tryGetRankList();
        // 是否已经上榜
        Rank his = findRankByRoleUid(snapshot.uid);
        if (list.size() >= getRankNum()) {
            Rank last = list.get(list.size() - 1);
            if (failCompareToLastOne(last.value, last.extraValue, value, extraValue)) {
                // 没有进排行榜
                return;
            }
        }
        long preValue = his == null ? 0 : his.value;
        long preExtraValue = his == null ? 0 : his.extraValue;
        if (his != null) {
            // 已经在榜上了
            his.updateOwner(snapshot, value, extraValue);
        } else {
            // 之前没有上榜
            Rank e = new Rank(snapshot, value, extraValue);
            if (list.size() >= getRankNum()) {
                // 如果排行榜已经满了，那就把最后一名给去掉
                list.remove(list.size() - 1);
            }
            list.add(e);
        }
        if (preValue != value || preExtraValue != extraValue) {
            sort();
        }
    }

    protected boolean failCompareToLastOne(long lastValue, long lastExtraValue, long value, long extraValue){
        boolean fail = false;
        if(type == Type.VALUE_BIG_EXTRA_BIG_NIUBI){
            fail = lastValue > value || (lastValue == value && lastExtraValue >= extraValue);
        }else if(type == Type.VALUE_BIG_EXTRA_SMALL_NIUBI){
            fail = lastValue > value || (lastValue == value && lastExtraValue <= extraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_BIG_NIUBI){
            fail = lastValue < value || (lastValue == value && lastExtraValue >= extraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_SMALL_NIUBI){
            fail = lastValue < value || (lastValue == value && lastExtraValue <= extraValue);
        }
        return fail;
    }

    protected Comparator<Rank> typeComparator(Type type){
        if(type == Type.VALUE_BIG_EXTRA_BIG_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .thenComparing(Rank::getExtraValue)
                    .reversed();
        }else if(type == Type.VALUE_BIG_EXTRA_SMALL_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .reversed()
                    .thenComparing(Rank::getExtraValue);
        }else if(type == Type.VALUE_SMALL_EXTRA_SMALL_NIUBI){
            return Comparator.comparing(Rank::getValue)
                    .thenComparing(Rank::getExtraValue);
        }else{
            //这个不确定，没试过
            return Comparator.comparing(Rank::getValue)
                    .reversed()
                    .thenComparing(Rank::getExtraValue)
                    .reversed();
        }
    }

    @Override
    public void sort(){
        tryGetRankList().sort(typeComparator(type).thenComparing(Rank::getRecordTime));
    }

    /**
     * 排序类型
     */
    public enum Type{
        /** value大的，extraValue大的牛逼 */
        VALUE_BIG_EXTRA_BIG_NIUBI,
        /** value小的， extraValue 大的牛逼 */
        VALUE_SMALL_EXTRA_BIG_NIUBI,
        /** value大的，extraValue小的牛逼 */
        VALUE_BIG_EXTRA_SMALL_NIUBI,
        /** value小的，extraValue小的牛逼 */
        VALUE_SMALL_EXTRA_SMALL_NIUBI
    }
}
